#ifndef _INC_MEMPOOL_H_
#define _INC_MEMPOOL_H_

class memPage_t;

class memPool_t
{
public:
	// Ctor
	memPool_t();

	// Ctor
	memPool_t(size_t amount);

	// Dtor
	~memPool_t();

	// Returns pool current position
	size_t getPosition() const;

	// Sets pool current position, returns true if successful, false otherwise
	bool setPosition(size_t pos);

	// Returns true if pool is empty, false otherwise
	bool isPoolEmpty() const;

	// Returns pool actual size
	size_t getPoolActualSize() const;

	// Returns pool total size (capacity)
	size_t getPoolTotalSize() const;

	// Returns amount of pages in pool
	size_t getNumOfPages() const;

	// Attempts to read data from pool according to given parameters, 
	// Returns true if successful, false otherwise
	bool read(void* const data, size_t size);

	// Attempts to read data from pool according to given parameters, 
	// Returns true if successful, false otherwise
	bool read(void* const data, size_t size, size_t position);
	
	// Attempts to write data to pool according to parameters, 
	// Returns true if successful, false otherwise
	bool write(const void* const data, size_t size);

	// Attempts to write data to pool according to parameters, 
	// Returns true if successful, false otherwise
	bool write(const void* const data, size_t size, size_t position);

	// Sets default page size
	static void setDefaultPageSize(size_t size);

	// Returns default page size
	static size_t getDefaultPageSize();

	// Prints pool info
	void printInfo();
	
private:
	// Copy Ctor
	memPool_t(const memPool_t& mp);

	// Operator=
	memPool_t& operator=(const memPool_t& mp);

	// Initializes pages according to given amount
	void initPages(size_t amount);

	// Returns true whether data with given size and position can be added to pool, false otherwise
	bool enoughSpaceInPool(size_t size, size_t position) const;

	// Reallocates space in pool according to size and position of new data
	void reallocateSpace(size_t size, size_t position);

	// Sets pool current position, returns relevant memory page if successful, NULL otherwise
	memPage_t* setPositionImpl(size_t pos);

	static size_t defaultPageSize;

	const size_t pageSize;
	size_t numOfPages;
	size_t position;

	memPage_t* firstPage;
	memPage_t* lastPage;
};

#endif // _INC_MEMPOOL_H_